package com.zy.explore.license.infrastructure.util;

import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * description 字符串工具类
 *
 * @author 🇨🇳中国印🇨🇳
 * @date 2022年04月17日 01:33:12
 **/

public class StrUtil {

    /**
     * 方法说明：字符串首字母小写
     *
     * @param s 年代
     * @return {@link String }
     */
    public static String firstCaseToLower(String s){
        if(Character.isLowerCase(s.charAt(0))) {
            return s;
        }
        return Character.toLowerCase(s.charAt(0)) + s.substring(1);
    }

    /***
     * 下划线命名转为驼峰命名
     * "CLIENT_NO" 转为驼峰命名：clientNo
     * @param underLineStr 下划线命名的字符串
     * @return 返回驼峰字符串
     */
    public static String underlineToHump(String underLineStr) {
        if (StringUtils.isEmpty(underLineStr)) {
            return "";
        }
        StringBuilder result = new StringBuilder();
        String underLineFlag = "_";
        String[] a = underLineStr.split(underLineFlag);
        for (String s : a) {
            if (!underLineStr.contains(underLineFlag)) {
                result.append(s);
                continue;
            }
            if (result.length() == 0) {
                result.append(s.toLowerCase());
            } else {
                result.append(s.substring(0, 1).toUpperCase());
                result.append(s.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }

    /***
     * 下划线命名转为驼峰命名，且首字母大写
     * "CLIENT_NO" 转为驼峰命名：clientNo
     * @param underLineStr 下划线命名的字符串
     * @return 返回驼峰字符串
     */
    public static String underlineToHumpFirstUpperCase(String underLineStr) {
        if (StringUtils.isEmpty(underLineStr)) {
            return "";
        }
        String result = underlineToHump(underLineStr);
        return result.substring(0, 1).toUpperCase() + result.substring(1);
    }

    /**
     * 方法说明：字段属性转表列
     *
     * @param field 字段
     * @return {@link String }
     */
    public static String fieldToColumn(String field) {
        return humpToUnderline(field);
    }

    /***
     * 驼峰命名转为下划线命名
     * "clientNo" 转为下划线命名：client_no
     * @param humpStr 驼峰命名的字符串
     * @return 返回下划线形式的字符串
     */
    public static String humpToUnderline(String humpStr) {
        StringBuilder sb = new StringBuilder(humpStr);
        int temp = 0;
        String underLineFlag = "_";
        if (!humpStr.contains(underLineFlag)) {
            for (int i = 0; i < humpStr.length(); i++) {
                if (Character.isUpperCase(humpStr.charAt(i))) {
                    sb.insert(i + temp, "_");
                    temp += 1;
                }
            }
        }
        return sb.toString().toLowerCase();
    }

    /**
     * mysql的数据类型转Java属性类型
     *
     * @param dataType mysql数据类型
     * @return 返回Java属性类型
     */
    public static String convertDataType(String dataType) {
        List<String> intList = Arrays.asList("int", "tinyint", "smallint");
        List<String> longList = Arrays.asList("bigint", "mediumint");
        List<String> stringList = Arrays.asList("char", "varchar", "text", "tinytext", "mediumtext", "longtext", "json");
        List<String> dateList = Arrays.asList("time", "datetime", "date", "timestamp");
        if (intList.contains(dataType)) {
            return "Integer";
        } else if (longList.contains(dataType)) {
            return "Long";
        } else if (Objects.equals(dataType, "bit")) {
            return "Boolean";
        } else if (stringList.contains(dataType)) {
            return "String";
        } else if (dateList.contains(dataType)){
            return "Date";
        } else if (Objects.equals(dataType, "float")) {
            return "Float";
        } else if (Objects.equals(dataType, "double")) {
            return "Double";
        } else if (Objects.equals(dataType, "decimal")) {
            return "BigDecimal";
        }
        return "";
    }


    /**
     * 正则表达
     * 手机号码由11位数字组成，
     * 匹配格式：前三位固定格式+后8位任意数
     * 此方法中前三位格式有：
     * 13+任意数
     * 15+除4的任意数
     * 18+除1和4的任意数
     * 17+除9的任意数
     * 147
     */
    public static boolean isMobileNumber(String str) throws PatternSyntaxException {
        String regExp = "^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))\\d{8}$";
        Pattern p = Pattern.compile(regExp);
        Matcher m = p.matcher(str);
        return m.matches();
    }

    /**
     * 将mysql的数据类型转换成mybatis的jdbcType
     *
     * @param dataType mysql数据类型
     * @return 返回mybatis的jdbcType类型
     */
    public static String convertToJdbcType(String dataType) {
        if (StringUtils.isEmpty(dataType)) {
            return "";
        }
        String jdbcType = dataType.toUpperCase();
        if (Objects.equals(jdbcType, "INT") || Objects.equals(jdbcType, "TINYINT") || Objects.equals(jdbcType, "SMALLINT")) {
            jdbcType = "INTEGER";
        } else if (Objects.equals(jdbcType, "TIME") || Objects.equals(jdbcType, "DATETIME")
                || Objects.equals(jdbcType, "DATE")) {
            jdbcType = "TIMESTAMP";
        } else if (Objects.equals(jdbcType, "TEXT") || Objects.equals(jdbcType, "TINYTEXT")
                || Objects.equals(jdbcType, "MEDIUMTEXT") || Objects.equals(jdbcType, "LONGTEXT")
                || Objects.equals(jdbcType, "JSON")) {
            jdbcType = "VARCHAR";
        } else if (Objects.equals(jdbcType, "BIT")) {
            jdbcType = "BOOLEAN";
        }
        return jdbcType;
    }

    /**
     * 去掉字符串指定的前缀
     * @param str 字符串名称
     * @param prefix 前缀数组
     */
    public static String removePrefix(String str, String[] prefix) {
        if (StringUtils.isEmpty(str)) {
            return "";
        } else {
            if (null != prefix) {
                for (String pf : prefix) {
                    if (str.toLowerCase().matches("^" + pf.toLowerCase() + ".*")) {
                        //截取前缀后面的字符串
                        return str.substring(pf.length());
                    }
                }
            }
            return str;
        }
    }

}
